﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcEngine.Core;
using MvcEngine.Core.Helpers;
using MvcEngine.Core.Repositories;
using MvcEngine.Core.Utils;
using System.Linq.Expressions;
using MvcEngine.Core.Extensions;
using MvcEngine.Mvc.Models;
using MvcEngine.Core.Pagination;
using MvcEngine.Gallery.Repositories;
using MvcEngine.Gallery.Models;
using MvcEngine.Core.Base;

namespace MvcEngine.Gallery.Managers
{
    public class GalleryImageManager : IGalleryImageManager
    {
        private readonly IGalleryImageRepository imageRepository = null;
        private readonly IGalleryImageCategoryRepository imageCategoryRepository = null;

        public GalleryImageManager(IGalleryImageRepository imageRepository, IGalleryImageCategoryRepository imageCategoryRepository)
        {
            this.imageRepository = imageRepository;
            this.imageCategoryRepository = imageCategoryRepository;
        }

        public static IGalleryImageManager Current
        {
            get { return IoC.Resolve<IGalleryImageManager>(); }
        }

        public void DeleteImage(Guid imageId)
        {
            using (IUnitOfWork unitOfWork = UnitOfWorkHelper.Get())
            {
                imageCategoryRepository.DeleteAll(imageId);
                imageRepository.Delete(imageId);
                unitOfWork.Commit();
            }
            CacheManager.Current.ClearCache(GalleryCacheKeys.GalleryImage.Category);
        }

        public void DeletePosts(Guid galleryId)
        {
            //imageRepository.DeleteAll(galleryId);
            CacheManager.Current.ClearCache(GalleryCacheKeys.GalleryImage.Category);
        }

        public IPagination<GalleryImage> GetImagesByCategory(Guid categoryId, LoadOptions options)
        {
            return CacheManager.Current.FromCache(string.Format(GalleryCacheKeys.GalleryImage.CategoryPaging, categoryId, options.PageNumber, options.PageSize), GalleryCacheKeys.GalleryImage.Category,
                () => imageRepository.GetByCategory(categoryId, options));
        }

        public GalleryImage GetImage(Guid imageId)
        {
            return CacheManager.Current.FromCache(string.Format(GalleryCacheKeys.GalleryImage.ImageId, imageId), GalleryCacheKeys.GalleryImage.Category,
                () => imageRepository.Get(imageId));
        }

        public void SaveImage(GalleryImage image, IList<GalleryImageCategory> categories)
        {
            Guard.ThrowIfEmptyGuid(image.Id);
            bool isUpdated = true;
            using (var unitOfWork = UnitOfWorkHelper.Get())
            {
                GalleryImage imageToSave = null;
                if (image.Id != Guid.Empty)
                {
                    imageToSave = imageRepository.Get(image.Id);
                }

                if (imageToSave == null)
                {
                    if (image.Id == Guid.Empty)
                    {
                        image.Id = Guid.NewGuid();
                    }
                    imageToSave = new GalleryImage { Id = image.Id };
                    imageToSave.CreatedDate = image.CreatedDate;
                    isUpdated = false;
                }

                imageToSave.Name = image.Name;
                imageToSave.Visible = image.Visible;
                imageToSave.Description = image.Description;
                if (!string.IsNullOrEmpty(image.Url))
                    imageToSave.Url = image.Url;
                imageToSave.Type = image.Type;
                imageToSave.CreatedDate = imageToSave.CreatedDate == DateTime.MinValue ? DateTime.Now : imageToSave.CreatedDate;
                imageToSave.ModifiedDate = DateTime.Now;

                if (isUpdated)
                {
                    imageRepository.Update(imageToSave);

                    var oldCategories = imageCategoryRepository.GetAll(image.Id);

                    var newCategories = from c in categories
                                        where !oldCategories.Any(i => i.CategoryId == c.CategoryId && i.ImageId == image.Id)
                                        select c;

                    var deletedCategories = from c in oldCategories
                                            where !categories.Any(i => i.CategoryId == c.CategoryId && i.ImageId == image.Id)
                                            select c;

                    foreach (var item in newCategories)
                    {
                        item.ModifiedDate = DateTime.Now;
                        item.CreatedDate = DateTime.Now;
                    }

                    imageCategoryRepository.InsertAll(newCategories);
                    imageCategoryRepository.DeleteAll(deletedCategories);
                }
                else
                {
                    imageRepository.Add(imageToSave);
                    foreach (var item in categories)
                    {
                        item.ModifiedDate = DateTime.Now;
                        item.CreatedDate = DateTime.Now;
                    }

                    imageCategoryRepository.InsertAll(categories);
                }
                unitOfWork.Commit();
            }
            CacheManager.Current.ClearCache(GalleryCacheKeys.GalleryImage.Category);
            CacheManager.Current.ClearCache(GalleryCacheKeys.GalleryCategory.Category);
        }

        public IPagination<GalleryImage> GetImagesByGallery(Guid galeryId, LoadOptions options)
        {
            return CacheManager.Current.FromCache(string.Format(GalleryCacheKeys.GalleryImage.GalleryPaging, galeryId, options.PageNumber, options.PageSize), GalleryCacheKeys.GalleryImage.Category,
                    () => imageRepository.GetByGallery(galeryId, options));
        }
    }
}
